import json
import leancloud
import datetime
import re
leancloud.init("FuEKBAKt7fr6CnVTfMVXKyMm-gzGzoHsz", "9Gw1lGPn1fgxJ3gKw04BltIU")
area = leancloud.Object.extend("Area")
area_data = leancloud.Object.extend("AreaData")
raw_data = leancloud.Object.extend("RawData")
query = raw_data.query
query.equal_to("event_name", "2019-nCoV")
query.descending("time")
f = query.first()
rawdata = json.loads(f.get("data"))

#丁香医生"suspectedIncr"一天更新一次，且在凌晨一段时间内的原始数据无法获得"suspectedIncr",可以依据此划分当天的数据是(前一天的中间数据, 前一天的最终数据, 当天的中间数据)
if rawdata[0].get("suspectedIncr") is None:                             #此时视为前一天的中间数据
    case = "ignore"                                                     #此时的操作为修改除"suspectedIncr"外的数据
elif re.search("suspectedIncr", query.find()[1].get("data")) is None:    #此时视为前一天的最终数据
    case = "last"                                                       #此时的操作为修改前一天数据，修改前一天时间为23:59:59
elif re.search("suspectedIncr", query.find()[2].get("data")) is None:    #此时视为当天的中间数据
    case = "new"                                                        #此时的操作为创建当天数据，注意将"suspectedIncr"设为0
else:                                                                   #此时视为当天的中间数据
    case = "refresh"                                                    #此时的操作为修改当天数据，注意将"suspectedIncr"设为0

area_save_list = list()
area_data_save_list = list()
for data in rawdata:
    query = area.query
    query.equal_to("event_name", "2019-nCoV")
    query.equal_to("name", data["provinceName"])
    if query.count() == 0:
        country = area()
        country.set("event_name", "2019-nCoV")
        country.set("name", data["provinceName"])
        country.set("parent_area_name", data["continents"])
        area_save_list.append(country)
    '''
    对国外数据单独处理，理由如下：
    1. 国外数据统计时间和人民日报发布时间在约北京时间0-6时之外是一样的，0-6时人民日报有延迟（可能约北京时间0-6点人民日报不上班）
    2. 人民日报发布时间和丁香医生更新时间在约北京时间23-8时之外是一样的，23-8时丁香医生有延迟（可能约北京时间23-8时丁香医生不上班）'''
    if data["provinceName"] != "中国":
        for t in ("confirmedCount", "curedCount", "deadCount"):
            time = f.get("time")
            query = area_data.query
            query.equal_to("event_name", "2019-nCoV")
            query.equal_to("area_name", data["provinceName"])
            query.equal_to("type", t)
            query.descending("time")
            if query.count() == 0 or query.first().get("time").date() != time.date():
                ad = area_data()
                ad.set("event_name", "2019-nCoV")
                ad.set("area_name", data["provinceName"])
                ad.set("type", t)
            else:
                ad = query.first()
            ad.set("time", time)
            ad.set("value", data[t])
            area_data_save_list.append(ad)
    
    else:
        for t in ("confirmedCount", "suspectedCount", "curedCount", "deadCount", "seriousCount", "suspectedIncr"):
            if t == "suspectedIncr":
                if case == "ignore":
                    continue
                elif case != "last":
                    data[t] = 0
            time = f.get("time")
            if case == "new":
                ad = area_data()
                ad.set("event_name", "2019-nCoV")
                ad.set("area_name", data["provinceName"])
                ad.set("type", t)
                ad.set("time", time)
            else:
                query = area_data.query
                query.equal_to("event_name", "2019-nCoV")
                query.equal_to("area_name", data["provinceName"])
                query.descending("time")
                query.equal_to("type", t)
                try:
                    ad = query.first()
                except:
                    print(data["provinceName"])
                    print(t)
                if case == "last":
                    time += datetime.timedelta(days=-1)
                    ad.set("time", datetime.datetime(time.year, time.month, time.day, 23, 59, 59))
            ad.set("value", data[t])
            area_data_save_list.append(ad)
        for pdata in data["cities"]:
            query = area.query
            query.equal_to("event_name", "2019-nCoV")
            query.equal_to("name", pdata["provinceShortName"])
            if query.count() == 0:
                p = area()
                p.set("event_name", "2019-nCoV")
                p.set("name", pdata["provinceShortName"])
                p.set("parent_area_name", data["provinceName"])
                area_save_list.append(p)
            '''
            问题1：有的省市一天发布多次报道，其中第一次应是前一天的24时
            问题2：有的省市发布报道时间较晚
            问题3：有的省市可能会漏报一天的疫情
            问题4：有的省市过去没有发布报道，无法和数据库中的数据作判断
            解决方案：分情况讨论
            1. 库无数据：新建为一天前最终数据
            2. 库数据时间两天前且数据无变动：新建为一天前中间数据
            3. 库数据时间一天前且数据值有变动且为中间数据：修改为一天前最终数据
            4. 库数据时间一天前且数据值有变动且为最终数据：新建为当天中间数据
            5. 库数据时间为当天且数据值有变动：修改为当天新的中间数据
            0. 其他情况不操作，case为0'''
            case = 0
            time = f.get("time")
            for t in ("confirmedCount", "curedCount", "deadCount"):
                query = area_data.query
                query.equal_to("event_name", "2019-nCoV")
                query.equal_to("area_name", pdata["provinceShortName"])
                query.descending("time")
                query.equal_to("type", t)
                if query.count() == 0:
                    case = 1
                    break
                elif time.date() + datetime.timedelta(days=-2) == query.first().get("time").date():
                    case = 2
                    break
                elif query.first().get("value") != pdata[t] and \
                        time.date() + datetime.timedelta(days=-1) == query.first().get("time").date() and \
                        query.first().get("time").time() < datetime.time(23, 59, 59):
                    case = 3
                    break
                elif query.first().get("value") != pdata[t] and \
                        time.date() + datetime.timedelta(days=-1) == query.first().get("time").date() and \
                        query.first().get("time").time() == datetime.time(23, 59, 59):
                    case = 4
                    break
                elif query.first().get("value") != pdata[t] and \
                        time.date() == query.first().get("time").date():
                    case = 5
                    break
            if case != 0:
                for t in ("confirmedCount", "curedCount", "deadCount"):
                    time = f.get("time")
                    if case == 1 or case == 2 or case == 4:
                        ad = area_data()
                        ad.set("event_name", "2019-nCoV")
                        ad.set("area_name", pdata["provinceShortName"])
                        ad.set("type", t)
                    else:
                        query = area_data.query
                        query.equal_to("event_name", "2019-nCoV")
                        query.equal_to("area_name", pdata["provinceShortName"])
                        query.descending("time")
                        query.equal_to("type", t)
                        ad = query.first()
                    if case == 1 or case == 3:
                        time += datetime.timedelta(days=-1)
                        ad.set("time", datetime.datetime(time.year, time.month, time.day, 23, 59, 59))
                    elif case == 2:
                        time += datetime.timedelta(days=-1)
                        ad.set("time", datetime.datetime(time.year, time.month, time.day, 12))
                    elif case == 4:
                        ad.set("time", time)
                    ad.set("value", pdata[t])
                    area_data_save_list.append(ad)
            
            for cdata in pdata["cities"]:
                if "外地" not in cdata["cityName"] and "明确" not in cdata["cityName"] and "未知" not in cdata["cityName"] and "确认" not in cdata["cityName"]:
                    if cdata["cityName"] in ["吉林", "乌海"]:
                        cdata["cityName"] += "市"
                    elif cdata["cityName"] in ["静安", "长宁", "徐汇", "奉贤", "黄浦", "虹口", "闵行", "青浦", "宝山", "嘉定", "松江", "金山", "杨浦", \
                                                "海淀", "大兴", "西城", "昌平", "丰台", "通州", "石景山", "顺义", "东城", "门头沟", "怀柔", \
                                                "宁河"]:
                        cdata["cityName"] += "区"
                    elif cdata["cityName"] == "浦东":
                        cdata["cityName"] += "新区"
                    elif cdata["cityName"] in ["白银市", "金昌市", "天水市", "平凉市", "吐鲁番市", "安阳市", "漯河市", "长垣县", "四平市", "澄迈县", "临高县", "陵水县", "琼海市", "东方市", "琼中县"]:
                        cdata["cityName"] = cdata["cityName"][:-1]
                    elif cdata["cityName"] in ["第八师石河子市", "第八师石河子", "石河子"]:
                        cdata["cityName"] = "第八师"
                    elif cdata["cityName"] == "胡杨河":
                        cdata["cityName"] = "第七师"
                    elif cdata["cityName"] == "宁东管委会":
                        cdata["cityName"] = "宁东"
                    elif cdata["cityName"] in ["大理", "红河", "德宏", "楚雄", "文山", "凉山"]:
                        cdata["cityName"] += "州"
                    query = area.query
                    query.equal_to("event_name", "2019-nCoV")
                    query.equal_to("name", cdata["cityName"])
                    if query.count() == 0:
                        c = area()
                        c.set("name", cdata["cityName"])
                        c.set("event_name", "2019-nCoV")
                        c.set("parent_area_name", pdata["provinceShortName"])
                        area_save_list.append(c)
                    '''
                    问题1：有的省市一天发布多次报道，其中第一次应是前一天的24时
                    问题2：有的省市发布报道时间较晚
                    问题3：有的省市可能会漏报一天的疫情
                    问题4：有的省市过去没有发布报道，无法和数据库中的数据作判断
                    解决方案：分情况讨论
                    1. 库无数据：新建为一天前最终数据
                    2. 库数据时间两天前：新建为一天前中间数据
                    3. 库数据时间一天前且数据值有变动且为中间数据：修改为一天前最终数据
                    4. 库数据时间一天前且数据值有变动且为最终数据：新建为当天中间数据
                    5. 库数据时间为当天且数据值有变动：修改为当天新的中间数据
                    0. 其他情况不操作，case为0'''
                    case = 0
                    time = f.get("time")
                    for t in ("confirmedCount", "curedCount", "deadCount"):
                        query = area_data.query
                        query.equal_to("event_name", "2019-nCoV")
                        query.equal_to("area_name", cdata["cityName"])
                        query.descending("time")
                        query.equal_to("type", t)
                        if query.count() == 0:
                            case = 1
                            break
                        elif time.date() + datetime.timedelta(days=-2) == query.first().get("time").date():
                            case = 2
                            break
                        elif query.first().get("value") != cdata[t] and \
                                time.date() + datetime.timedelta(days=-1) == query.first().get("time").date() and \
                                query.first().get("time").time() < datetime.time(23, 59, 59):
                            case = 3
                            break
                        elif query.first().get("value") != cdata[t] and \
                                time.date() + datetime.timedelta(days=-1) == query.first().get("time").date() and \
                                query.first().get("time").time() == datetime.time(23, 59, 59):
                            case = 4
                            break
                        elif query.first().get("value") != cdata[t] and \
                                time.date() == query.first().get("time").date():
                            case = 5
                            break
                    if case != 0:
                        for t in ("confirmedCount", "curedCount", "deadCount"):
                            time = f.get("time")
                            if case == 1 or case == 2 or case == 4:
                                ad = area_data()
                                ad.set("event_name", "2019-nCoV")
                                ad.set("area_name", cdata["cityName"])
                                ad.set("type", t)
                            else:
                                query = area_data.query
                                query.equal_to("event_name", "2019-nCoV")
                                query.equal_to("area_name", cdata["cityName"])
                                query.descending("time")
                                query.equal_to("type", t)
                                ad = query.first()
                            if case == 1 or case == 3:
                                time += datetime.timedelta(days=-1)
                                ad.set("time", datetime.datetime(time.year, time.month, time.day, 23, 59, 59))
                            elif case == 2:
                                time += datetime.timedelta(days=-1)
                                ad.set("time", datetime.datetime(time.year, time.month, time.day, 12))
                            elif case == 4:
                                ad.set("time", time)
                            ad.set("value", cdata[t])
                            area_data_save_list.append(ad)
i = 500
while i < len(area_save_list):
    area.save_all(area_save_list[i - 500:i])
    i += 500
area.save_all(area_save_list[i - 500:len(area_save_list)])
i = 500
while i < len(area_data_save_list):
    area_data.save_all(area_data_save_list[i - 500:i])
    i += 500
area_data.save_all(area_data_save_list[i - 500:len(area_data_save_list)])